#!/usr/bin/env python
# coding=utf-8
from __future__ import print_function
import time
import pyaudio
import wave
import rospy
import os
from contextlib import contextmanager
from robot_audio.srv import IAT, IATRequest, IATResponse
from robot_audio.srv import AIUI, AIUIRequest, AIUIResponse
from robot_audio.srv import Control, ControlRequest,ControlResponse
from robot_audio.srv import Mode, ModeRequest, ModeResponse
from robot_audio.srv import Nav, NavRequest, NavResponse
from robot_audio.srv import TTS, TTSRequest, TTSResponse
from robot_audio.srv import Collect, CollectRequest, CollectResponse
from robot_audio.srv import Awake, AwakeRequest, AwakeResponse

useSpeakerMic = True
useNeckTurn = True
@contextmanager
def no_alsa_error():
    try:
        asound = cdll.LoadLibrary('libasound.so')
        asound.snd_lib_error_set_handler(c_error_handler)
        yield
        asound.snd_lib_error_set_handler(None)
    except:
        yield
        pass

def play_audio_file(fname):
    """Simple callback function to play a wave file. By default it plays
    a Ding sound.

    :param str fname: wave file name
    :return: None
    """
    ding_wav = wave.open(fname, 'rb')
    ding_data = ding_wav.readframes(ding_wav.getnframes())
    with no_alsa_error():
        audio = pyaudio.PyAudio()
    	stream_out = audio.open(
        format=audio.get_format_from_width(ding_wav.getsampwidth()),
        channels=ding_wav.getnchannels(),
        rate=ding_wav.getframerate(), input=False, output=True)
    	stream_out.start_stream()
    	stream_out.write(ding_data)
    	time.sleep(0.2)
    	stream_out.stop_stream()
    	stream_out.close()
    	audio.terminate()
if __name__ == "__main__":
    awake_audio = "voice_config/awake.wav"
    rospy.init_node('voice_interaction')
    iatClient = rospy.ServiceProxy('voice_iat', IAT)
    aiuiClient = rospy.ServiceProxy('voice_aiui', AIUI)
    controlClient = rospy.ServiceProxy('voice_control', Control)
    modeClient = rospy.ServiceProxy('voice_mode', Mode)
    navClient = rospy.ServiceProxy('voice_nav', Nav)
    ttsClient = rospy.ServiceProxy('voice_tts', TTS)
    collectClient = rospy.ServiceProxy('voice_collect', Collect)
    awakeClient = rospy.ServiceProxy('voice_awake', Awake)
    rospy.wait_for_service('voice_iat')
    rospy.wait_for_service('voice_aiui')
    rospy.wait_for_service('voice_control')
    rospy.wait_for_service('voice_mode')
    rospy.wait_for_service('voice_nav')
    rospy.wait_for_service('voice_tts')
    rospy.wait_for_service('voice_collect')
    rospy.wait_for_service('voice_awake')

    awake_flag = False
    while not rospy.is_shutdown():
        while not awake_flag:
            fname =collectClient(True).voice_filename
            text = iatClient(fname).text
            if awakeClient(text).awake_flag:
                awake_flag = True
                print("什么事")
                play_audio_file(awake_audio)
            else:
                awake_flag = False
                print("休眠中，请说唤醒词唤醒")
            time.sleep(0.5)

        collectClient(True)
        msg = aiuiClient(fname, 'audio')
        cmd = msg.results.service
        if cmd == "nav":
            position = navClient(msg.results.strValue[1]).position
            #ttsClient(position, true)
        elif cmd == "control":
            res = controlClient(msg.results.strValue, msg.results.numValue[0]).result
            if not res:
                ttsClient("调用相关服务失败，请确保各个所需功能运行正常", True)
        else:
            ttsClient(msg.results.strValue[1], True)
        awake_flag = msg.awake_flag
 
